home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / video / xevil-1.000 / xevil-1 / locator.h < prev    next >
C/C++ Source or Header  |  1995-07-10  |  11KB  |  376 lines

  1. // "locator.h" The object locator.  
  2. // TAG: OL 
  3.  
  4. /*    Copyright (C) 1994  Steve Hardt
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 1, or (at your option)
  9.     any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     Steve Hardt 
  21.     hardts@athena.mit.edu hardts@media.mit.edu
  22.     hardts@r4002.3dem.bioch.bcm.tmc.edu
  23.     2043 McClendon
  24.     Houston, TX 77030
  25. */
  26.  
  27. /* Overview: 
  28. The locator can be seen as the collection of all physical objects in
  29. the game.  It draws all objects with the draw method.  The clock
  30. method goes through all the phases of one turn for all objects.  This
  31. is the only entity in the game that has a list of all the objects.
  32. Objects can be mapped and/or collidable.  An unmapped object is
  33. neither drawn nor collided.  An uncollidable object is drawn (if
  34. mapped) but not collided.  There is a message queue that objects can
  35. use to communicate with the ui object.  The locator does not need to
  36. be clocked for the queue to work. 
  37. The locator grid is the maximum size of the world.  I.e. it can be larger than
  38. the world. */
  39.  
  40.  
  41. #ifndef LOCATOR_H
  42. #define LOCATOR_H
  43.  
  44. #ifndef NO_PRAGMAS
  45. #pragma interface
  46. #endif
  47.  
  48.  
  49. // Include Files
  50. #include <iostream.h>
  51.  
  52. #include "utils.h"
  53. #include "coord.h"
  54. #include "id.h"
  55. #include "world.h"
  56.  
  57. class Intel;
  58. typedef Intel *IntelP;
  59. class Physical;
  60. typedef Physical *PhysicalP;
  61. class Human;
  62. typedef Human *HumanP;
  63. class Enemy;
  64. typedef Enemy *EnemyP;
  65. class Neutral;
  66. typedef Neutral *NeutralP;
  67.  
  68.  
  69. // Defines
  70. #define OL_LIST_MAX 1000
  71. #define OL_NEARBY_MAX OL_LIST_MAX
  72. #define OL_MESSAGES_MAX 300
  73.  
  74. #define OL_GRID_COL_MAX 4
  75. #define OL_GRID_ROW_MAX 4
  76. #define OL_GRID_WIDTH (OL_GRID_COL_MAX * WSQUARE_WIDTH) // In pixels.
  77. #define OL_GRID_HEIGHT (OL_GRID_ROW_MAX * WSQUARE_HEIGHT) // In pixels.
  78. #define OL_GRID_SIZE_MAX (max(OL_GRID_WIDTH,OL_GRID_HEIGHT))
  79. #define OL_GRID_HORIZ_MAX (W_COL_MAX_MAX / OL_GRID_COL_MAX + 1)// grid squares.
  80. #define OL_GRID_VERT_MAX (W_ROW_MAX_MAX / OL_GRID_ROW_MAX + 1) // grid squares.
  81.  
  82. // Data Structures.
  83. enum OLsig {OL_NO_SIG, OL_ALREADY_MANAGED, OL_NOT_FOUND};
  84.  
  85.  
  86.  
  87. // Class Declarations
  88. class Locator;
  89. class OLgridEntry;
  90. class OLshadowEntry;
  91.  
  92.  
  93. class OLentry {
  94.   friend class Locator;
  95.   friend class OLgridEntry; 
  96.   friend class OLshadowEntry;
  97.   friend class PhysicalIter;
  98.   
  99.   OLgridEntry *gridEntry; /* Only valid if mapped || flash. */
  100.   GLoc gloc; /* Set by OLgridEntry::insert.  Not nec. valid. */
  101.   OLshadowEntry *shadowEntry; /* Only valid if mapped || flash. */
  102.   GLoc shadowGloc; /* Set by OLshadowEntry::insert.  Not nec. valid. */
  103.  
  104.  
  105.   Boolean valid; 
  106.   Boolean reserved; // Meaningful when !valid.
  107.   PhysicalP physical; // Set when reserved.
  108.   
  109.   Boolean collided;
  110.   Boolean mapped; // Redundant.  Must be same as in object. 
  111.   Boolean flash; // Redundant.  Must be same as in object.
  112.   Boolean collidable;
  113. };
  114.  
  115.  
  116.  
  117. class OLgridEntry {
  118.  public:
  119.   OLgridEntry(OLentry *e) {entry = e; prev = next = NULL;}
  120.   
  121.   OLentry *get_entry() {return entry;}
  122.   PhysicalP get_physical() {return entry->physical;}
  123.   Boolean get_collided() {return entry->collided;}
  124.   Boolean get_mapped() {return entry->mapped;}
  125.   Boolean get_flash() {return entry->flash;}
  126.   OLshadowEntry *get_shadow_entry() {return entry->shadowEntry;}
  127.   const Area &get_area(); 
  128.  
  129.   int get_drawing_level();
  130.  
  131.   Boolean get_collidable() {return entry->collidable;}
  132.   OLgridEntry *get_next() {return next;}
  133.  
  134.   void set_collided(Boolean val) {entry->collided = val;}
  135.  
  136.   void insert(OLgridEntry *grid[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX],
  137.           const GLoc &gl);
  138.  
  139.   void remove();
  140.  
  141.   
  142.  private:
  143.   OLgridEntry *prev, *next;
  144.   OLentry *entry;
  145. };
  146. // This typedef not always used.  OLgridEntry::insert
  147. typedef OLgridEntry *OLgrid[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX];
  148.  
  149.  
  150.  
  151. class OLshadowEntry {
  152.  public:
  153.   OLshadowEntry() {entry = NULL; prev = next = NULL; orphaned = False;}
  154.   OLshadowEntry(const Area &a,OLentry *e) 
  155.     {area = a; entry = e; prev = next = NULL; orphaned = False;}
  156.   Boolean get_orphaned() {return orphaned;}
  157.  
  158.   OLentry *get_entry() {assert(entry); return entry;}
  159.   OLgridEntry *get_grid_entry() {assert(entry); return entry->gridEntry;}
  160.   const Area &get_area() {return area;}
  161.   Boolean draw_self() {return drawSelf;}
  162.   OLshadowEntry *get_next() {return next;}
  163.   /* NOTE: Several require that the shadowEntry is not orphaned. */
  164.  
  165.   void set_area(const Area &a) {area = a;}
  166.   void set_draw_self(Boolean val) {drawSelf = val;}
  167.   void set_orphaned() {orphaned = True; entry = NULL;}
  168.  
  169.  
  170.   void insert(OLshadowEntry *shadows[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX],
  171.           const GLoc &gl);
  172.   void remove();
  173.  
  174.  
  175.  private:
  176.   Boolean orphaned;
  177.   Area area;
  178.   Boolean drawSelf;
  179.   OLentry *entry;
  180.   OLshadowEntry *prev, *next;
  181. };
  182. typedef OLshadowEntry *OLshadows[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX];
  183.  
  184.  
  185.  
  186. // Iterator to extract all humans to be reincarnated.
  187. class Incarnator {
  188. public:
  189.   Incarnator(Locator &l) {n = 0; locator = &l;}
  190.   
  191.   HumanP operator () ();
  192.   /* EFFECTS: Extract next object to be reincarnated.  Return NULL if none.
  193.      The returned HumanP can only be extracted once. */
  194.  
  195.   
  196. private:
  197.   int n;
  198.   Locator *locator;
  199. };
  200.  
  201.  
  202.  
  203. class PhysicalIter {
  204.  public:
  205.   PhysicalIter(Locator &l) {n = 0; locator = &l;}
  206.  
  207.   PhysicalP operator() ();
  208.   /* EFFECTS: Yield all Physicals managed by the Locator. */
  209.   /* REQUIRES: Must be called outside of Locator::clock.  The Locator must 
  210.      not be modified while the PhysicalIter is being used. */
  211.  
  212.  
  213.  private:
  214.   int n;
  215.   Locator *locator;
  216. };
  217.  
  218.  
  219.  
  220. class Locator {
  221.   struct OLxdata 
  222.     {
  223.       Pixmap roomBuffer[Xvars::DISPLAYS_MAX]; // When changing rooms.
  224.       Pixmap buffer[Xvars::DISPLAYS_MAX];
  225.     };
  226.  
  227.   friend class Incarnator;
  228.   friend class PhysicalIter;
  229.  
  230.  
  231.  public:
  232.   enum { HUMANS_MAX = Xvars::HUMAN_COLORS_NUM, // <= UI_VIEWPORTS_MAX.
  233.      ENEMIES_MAX = 500, NEUTRALS_MAX = 400, DRAWING_LEVELS = 3,
  234.        };
  235.  
  236.   Locator(WorldP world);
  237.   /* EFFECTS: Create a new object locator with no managed objects. */
  238.  
  239.   static Boolean valid(const GLoc &gl) 
  240.     {return ((gl.vert >= 0) && (gl.horiz >= 0) && 
  241.          (gl.vert < OL_GRID_VERT_MAX) && (gl.horiz < OL_GRID_HORIZ_MAX));} 
  242.   /* EFFECTS:  Is gl a loc in the grid. */
  243.  
  244.   void add(PhysicalP p);
  245.   /* REQUIRES: p is not already managed. */
  246.   /* EFFECTS: p will be added to the list of managed physicals at the beginning
  247.      of the next clock.  p is initially mapped.  canCollide is set from p.
  248.      If called inside clock, object will not be added until beginning of next
  249.      clock.  You should not add something twice.  p is given a valid Id 
  250.      immediately (not at the next clock). */
  251.  
  252.   void get_nearby(PhysicalP nearby[OL_NEARBY_MAX],int &nitems,
  253.           PhysicalP p,int radius);
  254.   /* MODIFIES: nearby,nitems. */
  255.   /* EFFECTS:  Returns all objects that have their middles within radius of 
  256.      p's middle.  (I.e <= ) */  
  257.   /* NOTE: Expensive. */
  258.  
  259.   OLsig lookup(PhysicalP &p, const Id &id);
  260.   /* MODIFIES: p */
  261.   /* EFFECTS: Set p to be the object corresponding to id if it is managed 
  262.      and return OL_NO_SIG.  Otherwise return OL_NOT_FOUND. */
  263.  
  264.   PhysicalP lookup(const Id &id);
  265.   /* EFFECTS: Same as above except return NULL iff not found. */
  266.  
  267.   IntelP lookup(const IntelId &iId);
  268.   /* EFFECTS: Return the human or machine (enemy or neutral) Intel for iId if 
  269.      it exists, is registered, and is alive or reincarnating.  (Note that only 
  270.      Humans can be reincarnating.)  Otherwise, return NULL. */
  271.  
  272.   void draw(Drawable window,Xvars &xvars,int dpyNum,const Box &box);
  273.   /* REQUIRES: win is the same size as Box. (Adjusted for size of WSQUAREs.) */
  274.  
  275.   void reset();
  276.  
  277.   void clock();
  278.  
  279.  
  280.   // Message service.
  281.   void message_enq(char *msg);
  282.   /* EFFECTS:  Enqueue msg in the queue of messages for the ui.  The ui will 
  283.      free msg when it is done with it. */
  284.  
  285.   char *message_deq();
  286.   /* EFFECTS: Dequeue the next message of the message queue or return NULL if
  287.      the queue is empty. */
  288.  
  289.   void set_messages_ignore(Boolean msgIg) {messagesIgnore = msgIg;}
  290.   /* EFFECTS: While set to True, all enques messages will be immediately discarded. 
  291.    Default is False. */
  292.  
  293.  
  294.   // Player registry service.  Takes responsibility for reincarnation.
  295.   void register_human(HumanP); // Kept until reset.
  296.   void register_enemy(EnemyP); // Deleted as needed.
  297.   void register_neutral(NeutralP); // Deleted as needed.
  298.   
  299.   int humans_playing();
  300.   int enemies_alive();
  301.   int neutrals_alive();
  302.   
  303.   HumanP get_human(int n) {assert(n < humansNum);  return humans[n];}
  304.   /* REQUIRES: n < the number of humans registered */
  305.   /* NOTE: Does not guarantee any particular order. */
  306.  
  307.   
  308.  private:
  309.   enum { REINCARNATE_TIME = 70 };
  310.  
  311.   void add_now(PhysicalP);
  312.   void del_now(PhysicalP);
  313.  
  314.   void allign_flash_and_mapped(int n);
  315.   /* EFFECTS: Checks to see if physical n has changed its mapped or flash 
  316.      attribute.  If so, adjust the mapped attribute in *this. */
  317.   /* REQUIRES: n is a valid list index. */
  318.  
  319.   void init_x(Xvars &);
  320.  
  321.   Id reserve_list_entry(PhysicalP p);
  322.   /* EFFECTS: Reserve an entry in the list for p and return an Id for the
  323.      entry. */
  324.   
  325.   void collision_checks();
  326.   /* EFFECTS: Do collision checks between all registered objects. */
  327.  
  328.   GLoc compute_gloc(PhysicalP);
  329.   GLoc compute_gloc(const Area &);
  330.   /* EFFECTS: Compute the location in the grid for a physical or an area. */
  331.   /* NOTE: Ok to return invalid gloc. */
  332.  
  333.   void draw_area(Drawable window,Xvars &xvars,int dpyNum,const Box &room,
  334.          const Area &area,const GLoc &gloc);
  335.   /* REQUIRES: area is centered at gloc. window is the size of room*/
  336.   /* EFFECTS: Draws world and all objects overlapping area. */
  337.   /* NOTE: box does not have to be valid. */
  338.  
  339.   void reincarnate_clock();
  340.  
  341.  
  342.   // Data.
  343.   WorldP world;
  344.   int uniqueGen;
  345.   int listMax; // All valid entries in the list have index < listMax.
  346.   OLentry list[OL_LIST_MAX];
  347.   OLgrid grid;
  348.  
  349.   OLshadows shadows;
  350.   OLshadowEntry *shadowDelList[OL_LIST_MAX];
  351.   int shadowDelNum;
  352.  
  353.   PhysicalP addList[OL_LIST_MAX];
  354.   int addNum;
  355.  
  356.   Boolean xValid;
  357.   OLxdata xdata;
  358.  
  359.   // Message service.
  360.   char *messages[OL_MESSAGES_MAX];
  361.   int head,tail; 
  362.   Boolean messagesIgnore;
  363.  
  364.   // Player registry service.
  365.   HumanP humans[HUMANS_MAX];
  366.   EnemyP enemies[ENEMIES_MAX];
  367.   NeutralP neutrals[NEUTRALS_MAX];
  368.   int humansNum;
  369.   int enemiesNum;
  370.   int neutralsNum;
  371.   Boolean reincarnating[HUMANS_MAX]; // Just for humans.
  372.   Timer reincarnateTimers[HUMANS_MAX]; // Just for humans.
  373. };
  374. typedef Locator *LocatorP;
  375. #endif
  376.